Skip to content

Add ThreeMfDef FileDef subclass for 3MF (3D printing) files - #5628

Closed
FadhlanR wants to merge 1 commit into
mainfrom
cs-12054-3mf-filedef
Closed

Add ThreeMfDef FileDef subclass for 3MF (3D printing) files#5628
FadhlanR wants to merge 1 commit into
mainfrom
cs-12054-3mf-filedef

Conversation

@FadhlanR

Copy link
Copy Markdown
Contributor

Background and Goal

Adds ThreeMfDef, a FileDef subclass for .3mf (3D Manufacturing Format / 3D printing) files, so they index as a first-class file type. A .3mf is an OPC package (a ZIP) whose 3D/3dmodel.model XML carries title / designer / description / license and a unit — searchable text that is not present in the filename — so the subclass extracts it and feeds it into full-text search. Distinct icon + light metadata templates; no 3D viewer.

Resolves CS-12054.

Where to start

  • packages/base/3mf-meta-extractor.ts — the parse. fflate.unzipSync with a filter that records every entry name (→ hasThumbnail) while inflating only the *.model part; then decodes ≤256 KB of the model, cuts at <resources>/<build>, and regex-extracts the metadata + unit. Throws FileContentMismatchError on a non-ZIP or a ZIP with no model part.
  • packages/base/3mf-file-def.gtsThreeMfDef extends FileDef: the six searchable fields, extractAttributes (super + extract3mfMetadata), cube-3d-sphere icon, acceptTypes, and metadata-display isolated/embedded templates.
  • packages/runtime-common/file-def-code-ref.ts — the one-line registry entry that maps .3mf → ThreeMfDef and lights up urlNamesFile / isFileDefCodeRef.

Key decisions and non-obvious mechanics

  • Bounded on the indexing hot path. extractAttributes runs for every file during the index/prerender visit and 3MF files can be large, so we inflate only the model part and cap the XML parse at the header (metadata lives above <resources>; geometry lives below). Counting objects/triangles or reading the bounding box would require scanning past all vertices, so those are deferred.
  • Graceful fallback. A malformed/non-3MF file throws FileContentMismatchError, so the extractor falls back to a bare FileDef and the file still indexes — same pattern as Mp3Def/PngDef.
  • New dependency: fflate (~8 KB, isomorphic, added to the catalog + base). No ZIP/deflate library existed in the repo; base already imports npm runtime deps this way (super-fast-md5, awesome-phonenumber). Also added to host so the acceptance test can build fixtures.
  • MIME + binary. .3mf → model/3mf (IANA-registered; mime-db has no entry) and classified binary, so the CLI/bot don't treat the ZIP as text.
  • Deferred to follow-ups: a WebGL/three.js viewer (greenfield + prerender-render risk), the expensive geometry fields (triangle/vertex counts, bounding box, volume, object count), and surfacing the embedded thumbnail as the preview image.

Index .3mf files as a first-class file type. 3MF is an OPC (ZIP) package
whose 3dmodel.model XML carries title/designer/description/license and a
unit — searchable text that is absent from the filename — so the subclass
extracts it for full-text search. A bounded parse (inflate only the model
part, read the header up to the geometry) keeps extractAttributes cheap on
the indexing hot path; malformed files throw FileContentMismatchError and
fall back to a bare FileDef.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Preview deployments

Host Test Results

    1 files      1 suites   2h 37m 26s ⏱️
3 699 tests 3 679 ✅ 15 💤 0 ❌ 5 🔥
3 718 runs  3 693 ✅ 15 💤 5 ❌ 5 🔥

Results for commit 9de70cd.

For more details on these errors, see this check.

Realm Server Test Results

    1 files      1 suites   10m 49s ⏱️
1 943 tests 1 943 ✅ 0 💤 0 ❌
2 022 runs  2 022 ✅ 0 💤 0 ❌

Results for commit 9de70cd.

@FadhlanR

Copy link
Copy Markdown
Contributor Author

[Claude Code 🤖] Superseded by #5658, which unifies StlDef (CS-12053) and ThreeMfDef (CS-12054) under a shared ModelDef base. Closing in favor of that combined PR.

@FadhlanR FadhlanR closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant